using System;
using System.IO;
using Algorithms.Graph;

namespace Algorithms.Graph.Loaders
{
	public interface IGraphLoader
	{
		IGraph Load(string fileName);
	}

	public abstract class AbstractGraphLoader : IGraphLoader
	{
		protected string fileName;

		#region IGraphLoader Members	
		public string FileName
		{
			get 
			{
				return fileName;
			}
			set 
			{
				this.fileName = value;
				Load(fileName);
			}
		}

		public abstract IGraph Load (string fileName);


		#endregion

	}

	public interface IGraphFactory
	{
		IGraph GetGraph(string name, int numberOfVertices, bool isDirected);
	}

	public class PlainTextGraphLoader : IGraphLoader
	{
		protected IGraphFactory graphFactory;

		public void SetGraphFactory(IGraphFactory graphFactory)
		{
			this.graphFactory = graphFactory;
		}

		#region GraphLoader Members

		public IGraph Load(string fileName)
		{
			FileStream file = new FileStream(fileName, FileMode.Open);
			StreamReader sr = new StreamReader(file);

			int numberOfVertices = Int32.Parse(sr.ReadLine());
			bool isDirectedGraph = Boolean.Parse(sr.ReadLine());

			IGraph graph = graphFactory.GetGraph("", 
				numberOfVertices, isDirectedGraph);
			for(int i = 0; i < numberOfVertices; i++)
			{
				string line = sr.ReadLine();
				string[] connections = line.Split(new char[]{' '}, 5);
				for(int j = 0; j < connections.Length; j++)
				{
					int weight = Int32.Parse(connections[j]);
					graph.AddEdge(i, j, weight);
				}
			}
			file.Close();

			return graph;
		}

		#endregion

	}

	public class XmlGraphLoader : IGraphLoader
	{
		#region IGraphLoader Members

		public string FileName;

		public IGraph Load(string fileName)
		{
			// TODO:  Add XmlGraphLoader.Load implementation
			return null;
		}

		#endregion

	}


}